package com.yxq.mdt.app.widgets;

import android.graphics.Rect;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import java.util.Calendar;

/**
 * Created by walkingmen on 2016/12/17.
 * 处理复杂的点击 长按 长按抬起 长按滑动等事件
 */

public class BeautyTouchListener implements View.OnTouchListener {
    private static final String TAG = "SHF";
    private OnBeautyTouchListener mOnBeautyTouchLisener;
    private long longPressTipTime;

    public long getLongPressTipTime() {
        return longPressTipTime;
    }

    public void setLongPressTipTime(long longPressTipTime) {
        this.longPressTipTime = longPressTipTime;
    }

    public void setOnBeautyTouchLisener(OnBeautyTouchListener onBeautyTouchLisener) {
        mOnBeautyTouchLisener = onBeautyTouchLisener;
    }

    public BeautyTouchListener() {
    }

    public BeautyTouchListener(OnBeautyTouchListener onBeautyTouchLisener) {
        mOnBeautyTouchLisener = onBeautyTouchLisener;
    }

    private boolean touchOutside = false;
    private boolean touchInSide = false;
    private boolean longClickThreeMuch = false;
    private boolean haveTip = false;
    /**
     * ----------------
     */

    private static final long CLICK_SPACING_TIME = 300;

    private static final long LONG_PRESS_TIME = 500;


    /**
     * 当前触摸点相对于屏幕的坐标
     */

    private int mCurrentInScreenX;

    private int mCurrentInScreenY;


    /**
     * 触摸点按下时的相对于屏幕的坐标
     */

    private int mDownInScreenX;

    private int mDownInScreenY;

    /**
     * 点击次数
     */

    private int mClickCount = 0;


    /**
     * 当前点击时间
     */
    private long mCurrentClickTime;

    /**
     * 开始长按监听的时间
     */
    private long mLongClickStartTime = -1;


    private Handler mBaseHandler = new Handler();


    /**
     * 长按线程
     */

    private LongPressedThread mLongPressedThread;

    /**
     * 点击等待线程
     */

    private ClickPressedThread mPrevClickThread;
    /**
     * 长按等待三秒的进程
     */
    private LongTimePressThread mLongTimePressThread;


    @Override

    public boolean onTouch(View v, MotionEvent event) {
        //获取相对屏幕的坐标，即以屏幕左上角为原点
        float x;
        float y;

        //获取相对屏幕的坐标，即以屏幕左上角为原点

        mCurrentInScreenX = (int) event.getRawX();

        mCurrentInScreenY = (int) event.getRawY();

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
                haveTip = false;
                /**----------------*/
                x = event.getRawX();
                y = event.getRawY();
                if (isInside(v, x, y)) {
                    touchInSide = true;
                    touchOutside = false;
                } else {
                    touchInSide = false;
                    touchOutside = true;
                }
                Log.i(TAG, "SHF--onTouch---> ACTION_DOWN");
                /**----------------*/

                //记录Down下时的坐标
                mDownInScreenX = (int) event.getRawX();
                mDownInScreenY = (int) event.getRawY();

                //记录当前点击的时间
                mCurrentClickTime = Calendar.getInstance().getTimeInMillis();

                //刷新长按的开始时间
                mLongClickStartTime = -1;

                //点击次数加1
                mClickCount++;

                //取消上一次点击的线程
                if (mPrevClickThread != null) {

                    mBaseHandler.removeCallbacks(mPrevClickThread);

                }

                mLongPressedThread = new LongPressedThread();

                mBaseHandler.postDelayed(mLongPressedThread, LONG_PRESS_TIME);

                break;

            case MotionEvent.ACTION_MOVE: {
                /**----------------*/
                x = event.getRawX();
                y = event.getRawY();

                if (isInside(v, x, y)) {
                    touchInSide = true;
                    touchOutside = false;
                } else {
                    touchInSide = false;
                    touchOutside = true;
                }
                //如果长按超过了三秒 并且是碰到了外头  那么回调长按移动到了外头
                if (longClickThreeMuch && touchOutside && !haveTip) {
                    if (mOnBeautyTouchLisener != null) {
                        mOnBeautyTouchLisener.onBeautyTouchListener(OnBeautyTouchListener.LONG_MUCH_OUT_MOVE);
                        haveTip = true;
                    }
                }
                /**----------------*/

                mClickCount = 0; // 只要移动了 就没有点击事件了
                break;

            }

            case MotionEvent.ACTION_UP: {
                Log.i(TAG, "onTouch: ACTION_UP");
                //如果按住的时间超过了长按时间，那么其实长按事件已经出发生了,如果没有触发长按事件那么触发点击事件
                if (Calendar.getInstance().getTimeInMillis() - mCurrentClickTime <= LONG_PRESS_TIME) {
                    Log.i(TAG, "onTouch: 取消长按事件  触发click");
                    //取消注册的长按事件
                    mBaseHandler.removeCallbacks(mLongPressedThread);
                    mLongPressedThread = null;
                    mPrevClickThread = new ClickPressedThread();
                    mBaseHandler.postDelayed(mPrevClickThread, CLICK_SPACING_TIME);
                } else {//长按抬起事件处理
                    Log.i(TAG, "onTouch: 长按抬起");
                    if (mLongTimePressThread != null) {
                        mBaseHandler.removeCallbacks(mLongTimePressThread);
                    }
                    if (mOnBeautyTouchLisener != null) {
                        mOnBeautyTouchLisener.onBeautyTouchListener(OnBeautyTouchListener.LONG_CLICK_UP);
                    }

                    /**----------------*/
                    x = event.getRawX();
                    y = event.getRawY();
                    if (isInside(v, x, y)) {
                        touchInSide = true;
                        touchOutside = false;
                    } else {
                        touchInSide = false;
                        touchOutside = true;
                    }
                    Log.i(TAG, "onTouch: TOUCH_UP--touchInSide--" + touchInSide + "---longClickThreeMuch-" + longClickThreeMuch);
                    /**
                     * 如果如果触摸到外头并且长按超过了三秒
                     */
                    if (touchOutside && longClickThreeMuch) {
                        if (mOnBeautyTouchLisener != null) {
                            mOnBeautyTouchLisener.onBeautyTouchListener(OnBeautyTouchListener.LONG_MUCH_OUT_UP);
                        }
                        return true;
                    }
                    /**
                     * 如果如果触摸到外头并且长按没有超过了三秒
                     */
                    if (touchOutside && !longClickThreeMuch) {
                        if (mOnBeautyTouchLisener != null) {
                            mOnBeautyTouchLisener.onBeautyTouchListener(OnBeautyTouchListener.LONG_FEW_OUT_UP);
                        }
                        return true;
                    }

                    /**
                     * 如果在内部抬起 并且长按超过三秒
                     */
                    if (touchInSide && longClickThreeMuch) {
                        if (mOnBeautyTouchLisener != null) {
                            mOnBeautyTouchLisener.onBeautyTouchListener(OnBeautyTouchListener.LONG_MUCH_IN_UP);
                        }
                        return true;
                    }

                    /**
                     * 如果在内部抬起 并且长按不超过三秒
                     */
                    if (touchInSide && !longClickThreeMuch) {
                        if (mOnBeautyTouchLisener != null) {
                            mOnBeautyTouchLisener.onBeautyTouchListener(OnBeautyTouchListener.LONG_FEW_IN_UP);
                        }
                        return true;
                    }

                }

                if (mOnBeautyTouchLisener != null) {
                    mOnBeautyTouchLisener.onBeautyTouchListener(OnBeautyTouchListener.TOUCH_UP_COMPLETE);
                }
                resetTouchEvent();
                break;

            }

            default:
                break;

        }

        return true;

    }

    private void resetTouchEvent() {
        touchOutside = false;
        touchInSide = false;
        longClickThreeMuch = false;
        mLongClickStartTime = -1;
        haveTip = false;
    }

    /**
     * 判断是否移动
     *
     * @return
     */

    private boolean isMoved() {
        Log.i(TAG, "isMoved: mDownInScreenX---" + mDownInScreenX + "---mCurrentInScreenX---" + mCurrentInScreenX);
        //允许有5的偏差 在判断是否移动的时候
        return !(Math.abs(mDownInScreenX - mCurrentInScreenX) <= 5 && Math.abs(mDownInScreenY - mCurrentInScreenY) <= 5);
    }

    private class LongPressedThread implements Runnable {

        @Override

        public void run() {
            //这里处理长按事件
            if (mOnBeautyTouchLisener != null) {
                if (longPressTipTime > 0) {
                    mLongTimePressThread = new LongTimePressThread();
                    mBaseHandler.postDelayed(mLongTimePressThread, longPressTipTime);
                }
                mOnBeautyTouchLisener.onBeautyTouchListener(OnBeautyTouchListener.LONG_CLICK);
                mLongClickStartTime = Calendar.getInstance().getTimeInMillis();

            }
            mClickCount = 0;
        }

    }

    private class ClickPressedThread implements Runnable {

        @Override

        public void run() {

            //这里处理连续点击事件 mClickCount 为连续点击的次数
            if (mClickCount == 1 && mOnBeautyTouchLisener != null) {
                mOnBeautyTouchLisener.onBeautyTouchListener(OnBeautyTouchListener.CLICK);
            }
            mClickCount = 0;
        }

    }

    private class LongTimePressThread implements Runnable {

        @Override
        public void run() {
            if (mLongClickStartTime != -1) {
                longClickThreeMuch = true;
                mOnBeautyTouchLisener.onBeautyTouchListener(OnBeautyTouchListener.LONG_TOUCH_MUCH_TIME);
            }
        }
    }

    private boolean isInside(View view, float x, float y) {
        if (view == null) {
            return false;
        }
        //获取控件在屏幕的位置
        int[] location = new int[2];
        view.getLocationOnScreen(location);

        //控件相对于屏幕的x与y坐标
        int xScreen = location[0];
        int yScreen = location[1];
        Rect rect = new Rect(xScreen,
                yScreen,
                xScreen + view.getWidth(),
                yScreen + view.getHeight());
        return rect.contains((int) x, (int) y);
    }

    public void release() {
        if (mLongPressedThread != null) {
            mBaseHandler.removeCallbacks(mLongTimePressThread);
        }

        if (mLongTimePressThread != null) {
            mBaseHandler.removeCallbacks(mLongTimePressThread);
        }

        if (mPrevClickThread != null) {
            mBaseHandler.removeCallbacks(mPrevClickThread);

        }
    }

    public interface OnBeautyTouchListener {
        /**
         * 点击
         */
        int CLICK = 0;
        /**
         * 长按
         */
        int LONG_CLICK = 1;
        /**
         * 长按并且超出了longPressTipTime秒 并且移动出了view外 只会提示一次
         */
        int LONG_MUCH_OUT_MOVE = 2;

        /**
         * 长按并且超出了lptt秒  并且在view外抬起
         */
        int LONG_MUCH_OUT_UP = 3;
        /**
         * 长按并且超出了lptt秒 并且在view内抬起
         */
        int LONG_MUCH_IN_UP = 4;
        /**
         * 长按没有超过lptt秒 并且在view内抬起
         */
        int LONG_FEW_IN_UP = 5;
        /**
         * 长按没有超过十秒 在view外抬起
         */
        int LONG_FEW_OUT_UP = 6;

        /**
         * 长按抬起
         */
        int LONG_CLICK_UP = 7;
        /**
         * 抬起完成
         */
        int TOUCH_UP_COMPLETE = 8;
        /**
         * 长按没松手超过了lptt秒
         */
        int LONG_TOUCH_MUCH_TIME = 9;


        void onBeautyTouchListener(int type);
    }
}